/************************************************************
       (@_       
  _     ) \_______________________________________________
 (_)@8@8{}<_______________________________________________>
        )_/        
       (@
Liuxp
Website:        http://me.alipay.com/liuxp
Version：       1.0
File name：     PublishSocketUdp.cs
Author：        刘小平
Date：          ‎2014年‎09‎月‎19‎日，‏‎15:21:25
Description：   VS 发布工具
History：       在 AssemblyInfo.cs 里面的 AssemblyDescription 中查看
************************************************************/
using System;
using System.Net;
using Publish.Enum;
using System.Windows.Forms;
using Publish.Services;
using Publish.Services.SocketUdp;
using System.Collections.Generic;

namespace Publish
{
    public partial class Publish
    {
        #region Field

        /// <summary>
        /// 充当服务器 进行监听接收
        /// </summary>
        private SocketUdpServer socketUdpServer;

        /// <summary>
        /// 充当客户端
        /// </summary>
        public static SocketUdpClient SocketUdpClient;

        /// <summary>
        /// 谈话对方的局域网信息
        /// </summary>
        private LanInfo lanInfo = null;

        private String text = String.Empty;

        #endregion

        #region Method

        /// <summary>
        /// 初始化服务端
        /// </summary>
        private void InitServerSocketUdp()
        {
            text = Text;//临时测试用的标题

            LanList.CurrentLanList = new List<LanInfo>();
            socketUdpServer = SocketUdpServer.Instance;
            socketUdpServer.OnLineComplete += new SocketUdpServer.OnCompleteHander(OnLine_Event);
            socketUdpServer.OfflineComplete += new SocketUdpServer.OnCompleteHander(OffLine_Event);
            socketUdpServer.DatagramComplete += new SocketUdpServer.OnDatagramHander(Datagram_Event);
            socketUdpServer.ErrorAppear += new SocketUdpServer.OnCompleteHander(Error_Event);

            socketUdpServer.Listen();
            SocketUdpClient = new SocketUdpClient();
            SocketUdpClient.Broadcast(DatagramType.OnLine);

            //发布次数 委托事件
            PublishService.OnGetCountComplete += new PublishService.OnCompleteHander(OnGetCountComplete);
        }

        /// <summary>
        /// 初始化客户端
        /// </summary>
        private void InitClientSocketUdp()
        {
            String host = Dns.GetHostName();//欲交谈对象主机名
            //设置为正在交谈
            lanInfo = LanList.SetTalkState(host, TalkState.Talking);

            //绑定收到信息事件
            socketUdpServer.OnChatComplete += new SocketUdpServer.OnCompleteHander(ReceiveEvent);
            //给谈话的socket初始化endpoint
            SocketUdpClient = new SocketUdpClient(lanInfo.RemoteEndPoint);
        }

        #endregion

        #region Socket Event

        /// <summary>
        /// 接收信息回调事件
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="e"></param>
        private void ReceiveEvent(SocketUdpServer socket, EventArgs e)
        {
            //判断 远端的网络端点是否是当前的 打开的窗体
            if (String.CompareOrdinal(lanInfo.RemoteEndPoint.ToString(), socket.RemoteEndPoint.ToString()) == 0)
            {
                //lbxMessage.Invoke(new MyInvoke(AddLine), talkLan.Host, socket.Message);
                MessageBox.Show(socket.Message);
            }
        }

        /// <summary>
        /// 上线事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnLine_Event(SocketUdpServer sender, EventArgs e)
        {
            String host = sender.Message;
            //如果该上线的用户在局域网列表中不存在
            if (!LanList.CurrentLanList.Exists(x => x.Host == host))
            {
                while (!IsHandleCreated) ;
                //将上线用户添加进静态的局域网列表
                LanList.CurrentLanList.Add(new LanInfo()
                {
                    Host = host,
                    State = TalkState.Waiting,
                    RemoteEndPoint = sender.RemoteEndPoint
                });

                Text = text + " " + LanList.CurrentLanList.Count;
            }
        }

        /// <summary>
        /// 下线事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OffLine_Event(SocketUdpServer sender, EventArgs e)
        {
            String host = sender.Message;
            if (LanList.CurrentLanList.Exists(x => x.Host == host))
            {
                //判断是否是自己的主机下线 如果是自己的 则不需要操作
                if (String.CompareOrdinal(Dns.GetHostName(), host) != 0)
                {
                    //ilbUserList.Invoke(new MyInvoke(RemoveUser), LanList.CurrentLanList.FindIndex(x => x.Host == host).ToString());
                    //将该用户从局域网列表中移除

                    LanList.CurrentLanList.RemoveAll(x => x.Host == host);
                }

                Text = text + " " + LanList.CurrentLanList.Count;
            }
        }

        /// <summary>
        /// 广播事件
        /// </summary>
        /// <param name="sender"></param>
        private void Datagram_Event(Datagram sender)
        {
            //实时显示发布记录
            if (btnOpen.Text == Fewer)
                BindHistoryThreadStart();//读取发布历史列表

            if (sender.ProjectName == ProjectName)//收到广播，比对项目名称，若名称一直则触发事件
            {
                InitDictionaryListThreadStart();//重新初始化项目文件版本信息

                PublishService.BindPublishCountThreadStart();//读取当前项目发布次数
            }

            lblTime.Text = "Time：" + DateTime.Now.ToLongTimeString();
        }

        /// <summary>
        /// 出现错误的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Error_Event(SocketUdpServer sender, EventArgs e)
        {
            MessageBox.Show(sender.Message);
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        private void SendMessage(String message)
        {
            try
            {
                //String message = "中文";
                if (String.IsNullOrEmpty(message))
                {
                    MessageBox.Show("发送信息不能为空");
                }
                else
                {
                    SocketUdpClient.Send(message);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #region Data Event

        /// <summary>
        /// 读取当前项目发布次数
        /// </summary>
        private void OnGetCountComplete(Object count, EventArgs e)
        {
            SetControlText("Publish：" + count, lblPublish);
        }

        #endregion
    }
}
